freee Tech Night 「freeeにおけるモノリシック」
https://gyazo.com/194f3ae5e8c3593e38e79222738d38fc
会計freeeのデプロイを10倍早くした話
アジェンダ
日に1,3回
使用料金が高い…
直列で
LBから抜く必要があるので並列デプロイできない
サーバー台数が多いと50minかかる
検討した選択肢
EKSへの以降
モノリシックなものを移行したことはない
セキュリティ対策周りが弱かった
マイクロサービスを中心に本番運用したことある
サーバー台数2倍にする
イミュータブル・インフラストラクチャの実現
AWSがプロビジョンする時間がボトルネック
サーバー台数が希望数確保できる保証がない
アプリケーション・サーバーへのホットデプロイ
デプロイの中にあたらしいインスタンスを用意する
圧倒的に早い
イミュータブル・インフラストラクチャからは遠ざかる
デプロイ、ロールバック時間
影響範囲の観測が少ない
モノリスへのアプローチ
課題
アプリケーション・サーバーを安全に入れ替えたい
完全検証が困難
対象ドメイン全体を把握するのが困難
アプローチ
プランBの確保
変更対象を理解する
Unicornのライブラリを理解
リクエストをさばくまでの流れ
リクエストをさばいているかの処理をチェック
パラメータの使われ方と影響範囲
forkの処理も合わせて抑える
各ワーカープロセス側でつなげる
段階的リリース
パフォーマンス劣化やバグを検知する仕掛けを多層で容易
テスト環境での負荷試験
負荷試験コトハジメ
インクリメンタルに負荷試験を行う
ほかサービスでのリリース
規模の小さいサービスで先行リリース
本番環境へのカナリアリリース
本番リクエストを2%程度
移行してどうだったか
25分 => 2,3分へ短縮できた
一部本番に流出してしまった問題
Redis connection, Releasesの消失
時間・規模が必要そうな事象は発見しづらい
リプレイテストの仕組みなど
明らかに重くなったという部分はなくなった
今後
モノリスがEKSへ以降
モノリスの分割が進行中
自動カナリアリリースを準備中
データの構造から再検討するパフォーマンスチューニング
会計チーム
アジェンダ
freeeの監視周りについて簡単に
Slackに通知
ボトルネックのエンドポイント確認
Query
リアルタイム監視
indexの効率
フルスキャン
実行回数
メール通知
最近始めた
DB周りのパフォーマンス改善
indexのチューニング
貼る必要がある
必要なカラムにindexを貼る
利用できていない
実行計画を見て適切なindexを利用できていないクエリの修正
なぜ漏れるのか
仕訳modelと事業所modelとの関連がある
joinのときは事業所情報が入らないので改善前のクエリになる
注意していること
通常でやるか・ホットデプロイでやるか
無駄にindexをはらない
本番相当のデータで検討
クエリ変更でチューニング
対象データのrowが大きい
2000万行もある
rowをしぼってテーブルをクエリに加える
注意してること
テーブルのデータ増加の角度
クエリの結果が変わらないか
nullで減ってるときがある
アプリケーションの処理を入れる
データの持ち方の見直し
idではなくStringでjoin
関連のカラムを追加
マスタデータと共存する情報が存在する
UNION
ユーザ側にコピーしreadはユーザーデータのpみ
注意していること
マスタデータコピーのタイミング
大きくなってからだと修正コストが大
頻繁に変更するテーブルの場合
最初からクエリを分ける
テーブル構成の見直し
大量データを都度集計して表示している
集計テーブルを作成
圧縮率の高いテーブルを作成
画面上表示するパフォーマンスは上がる
新たな問題
登録時パフォーマンス劣化
ロックエラー
ギャップロックのロック待ち
データの不整合
対策
トランザクション
競合がおきないようにした
https://gyazo.com/a1bbbd6335e6046961800c189f3bf670
注意していること
集計テーブルのデータの切り方
登録時のコストが増える
集計データ表示のリアルタイム性を損なうのでユーザーへの告知
改善にはかなりの時間がかかる
機能の見直し
必要以上に実行されている可能性を疑う
集計データがHome画面アクセスで呼ばれる
全ユーザが必要とはしていない情報
対応
ユーザーアクションベースでの取得
非同期化
注意していること
ビジネスサイド(ユーザー)とのコミュニケーション
ユーザーメリットと運用個押すと
その他
N+1の解消
まとめ
チューニングは適時実施
マスターデータとの共存は可能な限り、避けましょう
構成の見直しは早めにしよう
エンジニアがドメインロジックに集中するためのコアパッケージ整備
サービス基盤チーム
コアパッケージ
各サービスで共通して使われるパッケージ
アジェンダ
作成に至る背景
freeeにおけるサービスの変化
主要なサービスはRails
基本同じ構成
社内gemやOSSを使用
ファットなRails
デプロイ時間
コード全体の見通し
昨日の責任の境界が不明瞭
2018年マイクロサービス開発が進む
サービスがどんどん出来た
Goのマイクロサービス
実装自体はサービスごとでバラバラな内容
モノリシックな問題を解決、それぞれで知見が溜まった
横のノウハウがあまりとれなかった
構成が若干違う気持ち悪さ
本来あるべき姿
ユーザに届けたい価値があって開発している
loggerやerrorも大事だが
各エンジニアがドメインロジックに集中できるようにする
使用策定、実装
機能の洗い出し
コードを全部読みドキュメント化
ヒアリング
気にかけた部分
contextを受け取れる場合、中継し後ろに渡している
異常系のときはerrorを返す、panic致命的な問題
goroutine safe
goのエコシステムを利用しているか
コアパッケージの作成
デファクトとしてのパッケージを作る
品質の保証と改修の恩恵を受けれるという意味でのデファクト
強制して使ってくれというものではない
利用者の技術剪定の余地は残す
拡張性
利用者側のユースケースで使えるように拡張性をもたせる
go-cloudを参考
HealthCheck pkg
簡単に組み込める
依存関係にある場所の解決は面倒
例:DBのコネクションを各パッケージに渡す
wireというパッケージを使う
wire
パッケージから設定の値など依存にあたる部分を切り出して
あとから注入する
Provider
必要な引数(依存性)を受け取り返り値として特定の型を返す
基本的に入っている
Injector
Providerを組み合わせて依存関係を解決し、特定の型を返す
作成の改善点
使われていないものの最適解を見つけるのは難しい
迷わず作りきってFBをもらうのがよい
導入
アナウンス
Qiita Teamsにドキュメントを書く
チャンネルに告知を流す
チュートリアルを作成
課題
パッケージが多すぎてなにがあるかわからない
どういう利点があるか伝えられてない
使われるものを作れてなかった
対応
エンジニアが集まる場で宣伝して認知度をあげる
マイクロサービス委員会
freeeの独自の文化
マイクロサービスのデファクトとは何かを話し合う
感想や欲しい機能の話し合いをして方針をきめる
機能のデファクト方針ドキュメントを作成
エラー通知について
各チームの目標にのせる
Goのチームは8〜10
導入の目処は立ってきた
振り返り
散らばってたノウハウを吸い上げ
デファクトについて言語化
共通認識を作れた
既存サービスの基底を見直し。改善